using AutoMapper;
using BackData;
using Domain;
using Domain.BOM;
using Domain.DTOs.BOMs;
using Infratructure;
using MediatR;
using System.Transactions;
using Team.API.Applocation.Command.BOM;
using Yitter.IdGenerator;

namespace Team.API.Applocation.Hanldler.BOM
{
    /// <summary>
    /// 更新成品BOM处理器
    /// </summary>
    public class UpdateProductBOMHandler : IRequestHandler<UpdateProductBOMCommand, APIResult<BOMDTO>>
    {
        private readonly IRepository<Bomtable> bomRepository;
        private readonly IRepository<Nlogmodel> nlogRepository;
        private readonly IMapper mapper;
        private readonly ILogger<UpdateProductBOMHandler> logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="bomRepository">BOM仓储</param>
        /// <param name="nlogRepository">日志仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public UpdateProductBOMHandler(
            IRepository<Bomtable> bomRepository,
            IRepository<Nlogmodel> nlogRepository,
            IMapper mapper,
            ILogger<UpdateProductBOMHandler> logger)
        {
            this.bomRepository = bomRepository;
            this.nlogRepository = nlogRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 处理更新成品BOM请求
        /// 使用事务同时操作BOM表和日志表，确保树形业务正常使用
        /// </summary>
        /// <param name="request">更新命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作结果</returns>
        public async Task<APIResult<BOMDTO>> Handle(UpdateProductBOMCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<BOMDTO>();
            // 获取当前登录人，如果为空则使用"系统"作为默认值
            var currentUserName = string.IsNullOrWhiteSpace(request.CurrentUserName) ? "系统" : request.CurrentUserName;

            // 记录接收到的用户名参数，用于调试
            logger.LogInformation($"[更新成品BOM] 接收到的CurrentUserName参数：{request.CurrentUserName ?? "null"}，最终使用的操作人：{currentUserName}");

            try
            {
                logger.LogInformation($"[更新成品BOM] 开始执行，操作人：{currentUserName}，BOM ID：{request.Id}");

                var entity = await bomRepository.GetByIdAsync(request.Id);
                if (entity == null || entity.IsDel)
                {
                    logger.LogWarning($"[更新成品BOM] 未找到需要更新的BOM，操作人：{currentUserName}，BOM ID：{request.Id}");
                    result.Code = StateCode.Fail;
                    result.Message = "未找到需要更新的成品BOM";
                    return result;
                }

                // 验证是否为成品BOM
                if (entity.Category != "成品")
                {
                    logger.LogWarning($"[更新成品BOM] 该BOM不是成品类型，操作人：{currentUserName}，BOM ID：{request.Id}，Category：{entity.Category}");
                    result.Code = StateCode.Fail;
                    result.Message = "只能更新成品类型的BOM";
                    return result;
                }

                // 如果修改了成品编码，检查新编码是否已存在
                if (entity.Itemcode != request.Itemcode)
                {
                    var existsByItemcode = bomRepository.GetAll()
                        .Any(x => x.Itemcode == request.Itemcode && x.Category == "成品" && x.Id != request.Id && x.IsDel == false);
                    if (existsByItemcode)
                    {
                        logger.LogWarning($"[更新成品BOM] 成品编码 {request.Itemcode} 已存在，操作人：{currentUserName}");
                        result.Code = StateCode.Fail;
                        result.Message = $"成品编码 {request.Itemcode} 已存在，请使用其他编码。";
                        return result;
                    }
                }

                // 保存更新前的数据用于日志记录
                var oldGoodsname = entity.Goodsname;
                var oldItemcode = entity.Itemcode;
                var oldVersion = entity.Version;

                // 更新BOM实体（不更新Parentid、ChildrenId，保持树形结构）
                entity.Itemcode = request.Itemcode;
                entity.Goodsname = request.Goodsname;
                entity.Spec = request.Spec ?? string.Empty;
                entity.Unit = request.Unit ?? string.Empty;
                entity.Version = request.Version ?? "1.0V";
                entity.Number = request.Number;
                entity.Remark = request.Remark ?? string.Empty;
                entity.IsUse = request.IsUse;
                // Category、Parentid、ChildrenId保持不变，确保树形业务正常

                // 创建操作日志实体
                var logEntity = new Nlogmodel
                {
                    Id = YitIdHelper.NextId(),
                    Message = $"{currentUserName}修改成品BOM信息，成品名称：{oldGoodsname} → {request.Goodsname}，成品编码：{oldItemcode} → {request.Itemcode}，版本：{oldVersion} → {request.Version}",
                    Category = "BOM",
                    Otherkey = entity.Id,
                    Operatingtime = DateTime.Now,
                    Operator = currentUserName,
                    IsDel = false
                };

                // 使用事务确保BOM表和日志表同时操作成功
                using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 更新BOM记录
                        var bomRows = await bomRepository.UpdateAsync(entity);
                        if (bomRows <= 0)
                        {
                            logger.LogError($"[更新成品BOM] BOM表更新失败，操作人：{currentUserName}，BOM ID：{request.Id}");
                            result.Code = StateCode.Fail;
                            result.Message = "成品BOM更新失败：数据更新失败";
                            return result;
                        }

                        // 添加操作日志
                        var logRows = await nlogRepository.AddAsync(logEntity);
                        if (logRows <= 0)
                        {
                            logger.LogError($"[更新成品BOM] 日志表插入失败，操作人：{currentUserName}，BOM ID：{entity.Id}");
                            result.Code = StateCode.Fail;
                            result.Message = "成品BOM更新失败：日志记录失败";
                            return result;
                        }

                        // 提交事务
                        transaction.Complete();

                        logger.LogInformation($"[更新成品BOM] 更新成功，操作人：{currentUserName}，BOM ID：{entity.Id}，成品名称：{request.Goodsname}");

                        result.Code = StateCode.OK;
                        result.Message = "成品BOM更新成功";
                        result.Result = mapper.Map<BOMDTO>(entity);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"[更新成品BOM] 事务执行失败，操作人：{currentUserName}，BOM ID：{request.Id}，错误信息：{ex.Message}");
                        result.Code = StateCode.Fail;
                        result.Message = $"成品BOM更新失败：{ex.Message}";
                        throw; // 抛出异常以触发事务回滚
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"[更新成品BOM] 处理失败，操作人：{currentUserName}，BOM ID：{request.Id}，错误信息：{ex.Message}");
                result.Code = StateCode.Fail;
                result.Message = $"成品BOM更新失败：{ex.Message}";
            }

            return result;
        }
    }
}

